<template>
    <view class="uni-filter-dropdown">
        <view class="dropdown-btn" @click="onDropdown">
            <view v-if="isSelect || isRange" class="icon-select" :class="{ active: canReset }"></view>
            <view v-if="isSearch" class="icon-search" :class="{ active: canReset }">
                <view class="icon-search-0"></view>
                <view class="icon-search-1"></view>
            </view>
            <view v-if="isDate" class="icon-calendar" :class="{ active: canReset }">
                <view class="icon-calendar-0"></view>
                <view class="icon-calendar-1"></view>
            </view>
        </view>
        <view v-if="isOpened" class="uni-dropdown-cover" @click="handleClose"></view>
        <view v-if="isOpened" class="dropdown-popup dropdown-popup-right" @click.stop>
            <!-- select-->
            <view v-if="isSelect" class="list">
                <label
                    v-for="(item, index) in dataList"
                    :key="index"
                    class="flex-r a-i-c list-item"
                    @click="onItemClick($event, index)"
                >
                    <check-box class="check" :checked="item.checked" />
                    <view class="checklist-content">
                        <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
                    </view>
                </label>
            </view>
            <view v-if="isSelect" class="flex-r opera-area">
                <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleSelectReset">
                    {{ resource.reset }}</view
                >
                <view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{ resource.submit }}</view>
            </view>
            <!-- search -->
            <view v-if="isSearch" class="search-area">
                <input v-model="filterValue" class="search-input" />
            </view>
            <view v-if="isSearch" class="flex-r opera-area">
                <view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{ resource.search }}</view>
                <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleSearchReset">
                    {{ resource.reset }}</view
                >
            </view>
            <!-- range -->
            <view v-if="isRange">
                <view class="input-label">{{ resource.gt }}</view>
                <input v-model="gtValue" class="input" />
                <view class="input-label">{{ resource.lt }}</view>
                <input v-model="ltValue" class="input" />
            </view>
            <view v-if="isRange" class="flex-r opera-area">
                <view class="flex-f btn btn-default" :class="{ disable: !canReset }" @click="handleRangeReset">
                    {{ resource.reset }}</view
                >
                <view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{ resource.submit }}</view>
            </view>
            <!-- date -->
            <view v-if="isDate">
                <uni-datetime-picker
                    ref="datetimepicker"
                    :value="dateRange"
                    type="datetimerange"
                    return-type="timestamp"
                    @change="datetimechange"
                    @mask-click="timepickerclose"
                >
                    <view></view>
                </uni-datetime-picker>
            </view>
        </view>
    </view>
</template>

<script>
import checkBox from "../uni-tr/table-checkbox.vue";

const resource = {
    reset: "重置",
    search: "搜索",
    submit: "确定",
    filter: "筛选",
    gt: "大于等于",
    lt: "小于等于",
    date: "日期范围"
};

const DropdownType = {
    Select: "select",
    Search: "search",
    Range: "range",
    Date: "date",
    Timestamp: "timestamp"
};

export default {
    name: "FilterDropdown",
    components: {
        checkBox
    },
    props: {
        filterType: {
            type: String,
            default: DropdownType.Select
        },
        filterData: {
            type: Array,
            default() {
                return [];
            }
        },
        mode: {
            type: String,
            default: "default"
        },
        map: {
            type: Object,
            default() {
                return {
                    text: "text",
                    value: "value"
                };
            }
        },
        filterDefaultValue: {
            type: [Array, String],
            default() {
                return "";
            }
        }
    },
    emits: ["change"],
    options: {
        virtualHost: true
    },
    data() {
        return {
            resource,
            enabled: true,
            isOpened: false,
            dataList: [],
            filterValue: this.filterDefaultValue,
            checkedValues: [],
            gtValue: "",
            ltValue: "",
            dateRange: [],
            dateSelect: []
        };
    },
    computed: {
        canReset() {
            if (this.isSearch) {
                return this.filterValue.length > 0;
            }
            if (this.isSelect) {
                return this.checkedValues.length > 0;
            }
            if (this.isRange) {
                return this.gtValue.length > 0 && this.ltValue.length > 0;
            }
            if (this.isDate) {
                return this.dateSelect.length > 0;
            }
            return false;
        },
        isSelect() {
            return this.filterType === DropdownType.Select;
        },
        isSearch() {
            return this.filterType === DropdownType.Search;
        },
        isRange() {
            return this.filterType === DropdownType.Range;
        },
        isDate() {
            return this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp;
        }
    },
    watch: {
        filterData(newVal) {
            this._copyFilters();
        },
        indeterminate(newVal) {
            this.isIndeterminate = newVal;
        }
    },
    created() {
        this._copyFilters();
    },
    methods: {
        _copyFilters() {
            let dl = JSON.parse(JSON.stringify(this.filterData));
            for (let i = 0; i < dl.length; i++) {
                if (dl[i].checked === undefined) {
                    dl[i].checked = false;
                }
            }
            this.dataList = dl;
        },
        openPopup() {
            this.isOpened = true;
            if (this.isDate) {
                this.$nextTick(() => {
                    if (!this.dateRange.length) {
                        this.resetDate();
                    }
                    this.$refs.datetimepicker.show();
                });
            }
        },
        closePopup() {
            this.isOpened = false;
        },
        handleClose(e) {
            this.closePopup();
        },
        resetDate() {
            let date = new Date();
            let dateText = date.toISOString().split("T")[0];
            this.dateRange = [dateText + " 0:00:00", dateText + " 23:59:59"];
        },
        onDropdown(e) {
            this.openPopup();
        },
        onItemClick(e, index) {
            let items = this.dataList;
            let listItem = items[index];
            if (listItem.checked === undefined) {
                items[index].checked = true;
            } else {
                items[index].checked = !listItem.checked;
            }

            let checkvalues = [];
            for (let i = 0; i < items.length; i++) {
                const item = items[i];
                if (item.checked) {
                    checkvalues.push(item.value);
                }
            }
            this.checkedValues = checkvalues;
        },
        datetimechange(e) {
            this.closePopup();
            this.dateRange = e;
            this.dateSelect = e;
            this.$emit("change", {
                filterType: this.filterType,
                filter: e
            });
        },
        timepickerclose(e) {
            this.closePopup();
        },
        handleSelectSubmit() {
            this.closePopup();
            this.$emit("change", {
                filterType: this.filterType,
                filter: this.checkedValues
            });
        },
        handleSelectReset() {
            if (!this.canReset) {
                return;
            }
            var items = this.dataList;
            for (let i = 0; i < items.length; i++) {
                let item = items[i];
                this.$set(item, "checked", false);
            }
            this.checkedValues = [];
            this.handleSelectSubmit();
        },
        handleSearchSubmit() {
            this.closePopup();
            this.$emit("change", {
                filterType: this.filterType,
                filter: this.filterValue
            });
        },
        handleSearchReset() {
            if (!this.canReset) {
                return;
            }
            this.filterValue = "";
            this.handleSearchSubmit();
        },
        handleRangeSubmit(isReset) {
            this.closePopup();
            this.$emit("change", {
                filterType: this.filterType,
                filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)]
            });
        },
        handleRangeReset() {
            if (!this.canReset) {
                return;
            }
            this.gtValue = "";
            this.ltValue = "";
            this.handleRangeSubmit(true);
        }
    }
};
</script>

<style lang="scss">
$uni-primary: #1890ff !default;

.flex-r {
    display: flex;
    flex-direction: row;
}

.flex-f {
    flex: 1;
}

.a-i-c {
    align-items: center;
}

.j-c-c {
    justify-content: center;
}

.icon-select {
    width: 14px;
    height: 16px;
    border: solid 6px transparent;
    border-top: solid 6px #ddd;
    border-bottom: none;
    background-color: #ddd;
    background-clip: content-box;
    box-sizing: border-box;
}

.icon-select.active {
    background-color: $uni-primary;
    border-top-color: $uni-primary;
}

.icon-search {
    width: 12px;
    height: 16px;
    position: relative;
}

.icon-search-0 {
    border: 2px solid #ddd;
    border-radius: 8px;
    width: 7px;
    height: 7px;
}

.icon-search-1 {
    position: absolute;
    top: 8px;
    right: 0;
    width: 1px;
    height: 7px;
    background-color: #ddd;
    transform: rotate(-45deg);
}

.icon-search.active .icon-search-0 {
    border-color: $uni-primary;
}

.icon-search.active .icon-search-1 {
    background-color: $uni-primary;
}

.icon-calendar {
    color: #ddd;
    width: 14px;
    height: 16px;
}

.icon-calendar-0 {
    height: 4px;
    margin-top: 3px;
    margin-bottom: 1px;
    background-color: #ddd;
    border-radius: 2px 2px 1px 1px;
    position: relative;
}
.icon-calendar-0:before,
.icon-calendar-0:after {
    content: "";
    position: absolute;
    top: -3px;
    width: 4px;
    height: 3px;
    border-radius: 1px;
    background-color: #ddd;
}
.icon-calendar-0:before {
    left: 2px;
}
.icon-calendar-0:after {
    right: 2px;
}

.icon-calendar-1 {
    height: 9px;
    background-color: #ddd;
    border-radius: 1px 1px 2px 2px;
}

.icon-calendar.active {
    color: $uni-primary;
}

.icon-calendar.active .icon-calendar-0,
.icon-calendar.active .icon-calendar-1,
.icon-calendar.active .icon-calendar-0:before,
.icon-calendar.active .icon-calendar-0:after {
    background-color: $uni-primary;
}

.uni-filter-dropdown {
    position: relative;
    font-weight: normal;
}

.dropdown-popup {
    position: absolute;
    top: 100%;
    background-color: #fff;
    box-shadow:
        0 3px 6px -4px #0000001f,
        0 6px 16px #00000014,
        0 9px 28px 8px #0000000d;
    min-width: 150px;
    z-index: 1000;
}

.dropdown-popup-left {
    left: 0;
}

.dropdown-popup-right {
    right: 0;
}

.uni-dropdown-cover {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: transparent;
    z-index: 100;
}

.list {
    margin-top: 5px;
    margin-bottom: 5px;
}

.list-item {
    padding: 5px 10px;
    text-align: left;
}

.list-item:hover {
    background-color: #f0f0f0;
}

.check {
    margin-right: 5px;
}

.search-area {
    padding: 10px;
}

.search-input {
    font-size: 12px;
    border: 1px solid #f0f0f0;
    border-radius: 3px;
    padding: 2px 5px;
    min-width: 150px;
    text-align: left;
}

.input-label {
    margin: 10px 10px 5px 10px;
    text-align: left;
}

.input {
    font-size: 12px;
    border: 1px solid #f0f0f0;
    border-radius: 3px;
    margin: 10px;
    padding: 2px 5px;
    min-width: 150px;
    text-align: left;
}

.opera-area {
    cursor: default;
    border-top: 1px solid #ddd;
    padding: 5px;
}

.opera-area .btn {
    font-size: 12px;
    border-radius: 3px;
    margin: 5px;
    padding: 4px 4px;
}

.btn-default {
    border: 1px solid #ddd;
}

.btn-default.disable {
    border-color: transparent;
}

.btn-submit {
    background-color: $uni-primary;
    color: #ffffff;
}
</style>
